package model;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.ForeignKey;

@Entity
@Table(name = "item_movimento")
public class ItemMovimento {
	
	@Id
	@GeneratedValue (strategy = GenerationType.IDENTITY)
	private Long id;

	@Column(name = "qtd_peca")
	private Integer quantidadePeca;

	@Column(name = "vlr_servico", precision = 15, scale = 2)
	private Double valorServico;

	@Column(name = "vlr_peca", precision = 15, scale = 2)
	private Double valorPeca;
	
	@Transient
	private Double subTotal;

	@ManyToOne(fetch = FetchType.EAGER)
	@ForeignKey(name = "fk_servico")
	private Servico servico;
	
	@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
	@ForeignKey(name = "fk_peca")
	private Peca peca;
	
	@ManyToOne(fetch = FetchType.EAGER, optional = false)
	@ForeignKey(name="fk_movimentacao")
	private Movimentacao movimentacao;
	
	@Transient
	private Integer quantidadePecaAnterior;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Integer getQuantidadePeca() {
		return quantidadePeca != null ? quantidadePeca : 0;
	}

	public void setQuantidadePeca(Integer quantidadePeca) {
		this.quantidadePeca = quantidadePeca;
	}

	public Double getValorServico() {
		return valorServico  != null ? valorServico : 0D;
	}

	public void setValorServico(Double valorServico) {
		this.valorServico = valorServico;
	}

	public Double getValorPeca() {
		return valorPeca != null ? valorPeca : 0D;
	}

	public void setValorPeca(Double valorPeca) {
		this.valorPeca = valorPeca;
	}

	public Servico getServico() {
		return servico;
	}

	public void setServico(Servico servico) {
		this.servico = servico;
	}

	public Movimentacao getMovimentacao() {
		return movimentacao;
	}

	public void setMovimentacao(Movimentacao movimentacao) {
		this.movimentacao = movimentacao;
	}

	public Peca getPeca() {
		return peca;
	}

	public void setPeca(Peca peca) {
		this.peca = peca;
	}
	
	public Integer getQuantidadePecaAnterior() {
		return quantidadePecaAnterior != null ? quantidadePecaAnterior : 0;
	}

	public void setQuantidadePecaAnterior(Integer quantidadePecaAnterior) {
		this.quantidadePecaAnterior = quantidadePecaAnterior;
	}

	// ------------------------------------------------------
		
	public void alimentaQtdPecaAnterior(){
		this.setQuantidadePecaAnterior(this.getQuantidadePeca());		
	}
	
	@PostPersist
	private void baixaMovimentoInsercao(){
		if (this.getPeca() != null){
			if(this.getMovimentacao().getTipo().equals("C")) {
				this.getPeca().setEstoque(this.getPeca().getEstoque() + this.quantidadePeca);
			} else {
				this.getPeca().setEstoque(this.getPeca().getEstoque() - this.quantidadePeca);
			}
		}
	}

	@PostUpdate
	private void baixaMovimentoAlteracao(){
		if (this.getPeca() != null){
			Integer estoqueAtual = this.getPeca().getEstoque();
			
			if(this.getMovimentacao().getTipo().equals("C")) {
				if (this.getQuantidadePeca() > this.getQuantidadePecaAnterior() ) {
					this.getPeca().setEstoque(estoqueAtual + (this.quantidadePeca - this.quantidadePecaAnterior));
				} else {
					this.getPeca().setEstoque(estoqueAtual - Math.abs((this.quantidadePeca - this.quantidadePecaAnterior)));
				}
			} else {
				if (this.getQuantidadePeca() > this.getQuantidadePecaAnterior() ) {
					this.getPeca().setEstoque(estoqueAtual - (this.quantidadePeca - this.quantidadePecaAnterior));
				} else {
					this.getPeca().setEstoque(estoqueAtual + Math.abs((this.quantidadePeca - this.quantidadePecaAnterior)));
				}
			}
			
			if (this.getQuantidadePeca() == 0) {
				this.peca = null;
				this.quantidadePecaAnterior = null;
				this.valorPeca = null;
				this.quantidadePeca = null;
			}
		}
	}
	
	@PostRemove
	private void baixaMovimentoExclusao(){
		if (this.getPeca() != null){
			if (this.getMovimentacao().getTipo().equals("C")) {
				this.getPeca().setEstoque(this.getPeca().getEstoque() - this.quantidadePeca);
			} else {
				this.getPeca().setEstoque(this.getPeca().getEstoque() + this.quantidadePeca);				
			}			
		}
	}

	@Override
	public String toString() {
		return "ItemMovimento [" +
				"id=" + id + ", " +
				"quantidadePeca=" + quantidadePeca + ", " +
				"valorServico=" + valorServico + ", " +
				"valorPeca=" + valorPeca + ", " +
				"servico=" + servico + ", " +
				"peca=" + peca + ", " +
				"movimentacao=" + movimentacao.getId() + ", " +
				"quantidadePecaAnterior=" + quantidadePecaAnterior + "]";
	}

	public Double getSubTotal() {
		subTotal = this.getQuantidadePeca() * this.getValorPeca();
		return subTotal;
	}

}
